#include <iostream>
#include <string>
#include <unistd.h>
#include <stdio.h>
#include "face_api_helper.h"
#include "thread/taskqueue.h"
#include "thread/taskthreadmanager.h"
#include "track.h"
#include "config.h"
#include <signal.h>
#include "log/logger.h"

using namespace std;
using namespace thread;

bool bQuit = false;
void handler(int signo)
{
	std::cout << "capture a SIGTERM signal,system is quiting... " << std::endl;
	bQuit = true;
}


void parse_argv(int argc, char* argv[])
{
	int ch = 0;
	while ((ch = getopt(argc, argv, "u:r:f:t:s:n:m:i:p:z:h")) != -1)
	{

		printf("optind: %d\n", optind);
		switch (ch) 
		{

			case 'u':
				printf("HAVE option: -u\n"); 
				printf("The argument of -u is %s\n\n", optarg);
				Config::video_url = optarg;
				break;
			case 'r':
				printf("HAVE option: -r\n");
				printf("the argument of -r is frame rate %s\n\n",optarg);
				Config::frame_rate = atoi(optarg) > 25 ?  25 : atoi(optarg);
				break;
			case 'f':
				printf("HAVE option: -f\n");
				printf("the argument of -f is %s\n\n",optarg);
				Config::frame_per_sec = atoi(optarg) > 5 ? 5 : atoi(optarg);
				break;
			case 't':
				printf("HAVE option: -t\n"); 
				printf("The argument of -t is thread num %s\n\n", optarg);
				Config::worker_count = atoi(optarg);

				break;
			case 's':
				printf("HAVE option: -s\n");
				printf("the argument of -s is  min score%s\n\n",optarg);
				Config::min_score = stof(optarg) >= 1 ? 0.999999 : stof(optarg);
				break;
			case 'n':
				printf("HAVE option: -n\n");
				printf("the argument of -n is max face num %s\n\n",optarg);
				Config::max_face_num = atoi(optarg) > 5 ? 5 : atoi(optarg);
				break;
			case 'm':
				printf("HAVE option: -m\n"); 
				printf("The argument of -i is machine id %s\n\n", optarg);
				Config::machine_id = optarg;
				break;

			case 'i':

				printf("HAVE option: -i\n"); 
				printf("The argument of -i is face httpd ip %s\n\n", optarg);
				Config::face_httpd_ip = optarg;
				break;

			case 'p':
				printf("HAVE option: -p\n");
				printf("the argument of -p is face httpd port %s\n\n",optarg);
				Config::face_httpd_port = atoi(optarg);
				break;

			case 'z':
				printf("HAVE option: -z\n"); 
				printf("The argument of -z is work mode %s\n\n", optarg);
				Config::mode = optarg;
				break;

			case 'h':
				printf("all option:\n");
				printf("  -u: video url. rtsp hls etc...");
				printf("  -r: frame rate.default 25");
				printf("  -f: track frame per second, default 2");
				printf("  -t: work thread. default 1");
				printf("  -s: track face min score,default 0.980000");
				printf("  -n: track max face num per frame,fefault 5");
				printf("  -m: video machine id");
				printf("  -i: face api httpd server host");
				printf("  -p: face api httpd server port");
				printf("  -z: work mode: all;track;detect");
				exit(0);
			case '?':
				printf("Unknown option: %c\n",(char)optopt);
				break;
		}
	}

}



int main(int argc,char* argv[])
{
	string process(argv[0]);
	process = process.substr(2,-1); // remove "./"
	LOG_OPEN( process.c_str(), LOG_PID, LOG_LOCAL0);

	signal(SIGTERM,handler);

	parse_argv(argc,argv);
	if( Config::video_url.empty() ) {
		std::cout << "not rtsp url input" << std::endl;
		LOG(LOG_ERR,"no rtsp url input");
		return -1;
	}

	if( Config::machine_id.empty() ) {
		std::cout << "not machine id input" << std::endl;
		LOG(LOG_ERR,"no video machine id input");
		return -1;
	}

    int ret = FaceApiHelper::getInstance()->sdk_init(false);
	if(!FaceApiHelper::getInstance()->is_auth()) {
		LOG(LOG_ERR,"face api sdk is not auth");
		return -1;
	}

	Config::dump();
	//初始化线程池
	std::map<uint32_t, TaskQueue> map_task_queue;
	for(uint32_t i = 0; i < Config::worker_count; i++ ){
		TaskQueue queue;
		map_task_queue[i] = queue;
	}
	TaskThreadManager taskThreadPool(Config::worker_count,map_task_queue);
	taskThreadPool.Init();
	taskThreadPool.Start();

	LOG(LOG_INFO,"faceTrack server start...");
	//开始检测人脸	
	FaceTrack faceTrack;
	faceTrack.Run(bQuit,map_task_queue);

	LOG(LOG_INFO,"faceTrack server stop...");

    return 0;
}


